﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using BrainTechLLC;
using BrainTechLLC.FilterExtensions;


namespace ImageAppViewModels
{
    public class FilterCollectionCollectionViewModel : ObservableCollection<FilterCollectionViewModel>
    {        
        protected FastSmartWeakEvent<EventHandler<NotifyCollectionChangedEventArgs>> _filterCollectionsChanged = new FastSmartWeakEvent<EventHandler<NotifyCollectionChangedEventArgs>>();
        public event EventHandler<NotifyCollectionChangedEventArgs> FilterCollectionsChanged { add { _filterCollectionsChanged.Add(value); } remove { _filterCollectionsChanged.Remove(value); } }

        protected FastSmartWeakEvent<EventHandler<ObjectEventArgs<FilterCollection>>> _singleFilterCollectionChanged = new FastSmartWeakEvent<EventHandler<ObjectEventArgs<FilterCollection>>>();
        public event EventHandler<ObjectEventArgs<FilterCollection>> SingleFilterCollectionChanged { add { _singleFilterCollectionChanged.Add(value); } remove { _singleFilterCollectionChanged.Remove(value); } }

        protected FilterCollectionCollection _collection;

        public ObservableCollection<string> _filterCollectionNames;

        public FilterCollectionViewModel FindByName(string name)
        {
            return this.FirstOrDefault((vm) => vm.CollectionName.Equals(name, StringComparison.OrdinalIgnoreCase));
        }

        public ObservableCollection<string> FilterCollectionNames
        {
            get
            {
                if (_filterCollectionNames == null)
                {
                    ObservableCollection<string> names = new ObservableCollection<string>();

                    foreach (var vm in this)
                    {
                        names.Add(vm.CollectionName);
                    }

                    names.Add("Blur Filters 1");
                    names.Add("Blur Filters 2");
                    names.Add("Comparison Filters");

                    Interlocked.CompareExchange<ObservableCollection<string>>(ref _filterCollectionNames, names, null);
                }

                return _filterCollectionNames;
            }
            set
            {
                if (_filterCollectionNames != value)
                {
                    _filterCollectionNames = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("FilterCollectionNames"));
                }
            }
        }

        public void SetCurrentGeneration(int newGeneration, NotifyCollectionChangedEventArgs e)
        {
            if (_collection.CurrentGeneration != newGeneration)
            {
                _collection.SetCurrentGeneration(newGeneration, e);
                OnPropertyChanged(new PropertyChangedEventArgs("CurrentGeneration"));
            }
        }

        public int CurrentGeneration
        {
            get { return _collection.CurrentGeneration; }
        }

        public FilterCollectionCollectionViewModel(FilterCollectionCollection collection)
        {
            _collection = collection;
            _collection.FilterCollectionsChanged += new EventHandler<NotifyCollectionChangedEventArgs>(_collection_FilterCollectionsChanged);
            _collection.SingleFilterCollectionChanged += new EventHandler<ObjectEventArgs<FilterCollection>>(_collection_SingleFilterCollectionChanged);

            foreach (var item in collection)
            {
                this.Add(new FilterCollectionViewModel(item));
            }
        }

        void _collection_SingleFilterCollectionChanged(object sender, ObjectEventArgs<FilterCollection> e)
        {
            _singleFilterCollectionChanged.Raise(this, e);
        }

        void _collection_FilterCollectionsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            _filterCollectionsChanged.Raise(this, e);
        }

        public int FindIndex(FilterCollectionViewModel model)
        {
            for (int n = 0; n < Count; n++)
            {
                if (this[n] == model)
                    return n;
            }
            return -1;
        }

        public void MoveItemLeft(FilterCollectionViewModel vm)
        {
            int index = FindIndex(vm);

            if (index <= 0)
                return;

            MoveItemFromTo(index, index - 1);
        }

        public void MoveItemLeftAll(FilterCollectionViewModel vm)
        {
            int index = FindIndex(vm);

            if (index <= 0)
                return;

            MoveItemFromTo(index, 0);
        }

        public void MoveItemRightAll(FilterCollectionViewModel vm)
        {
            int index = FindIndex(vm);

            if (index < 0 || index >= Count - 1)
                return;

            MoveItemFromTo(index, Count - 1);
        }

        public void MoveItemRight(FilterCollectionViewModel vm)
        {
            int index = FindIndex(vm);

            if (index < 0 || index >= Count - 1)
                return;

            MoveItemFromTo(index, index + 1);
        }

        public void MoveItemFromTo(int oldPosition, int newPosition)
        {
            _collection.Move(oldPosition, newPosition);
            Move(oldPosition, newPosition);
        }

        public void Save(string path)
        {
            _collection.Save(path);
        }

        public void AddFilterCollection(FilterCollection filter)
        {
            _collection.AddFilterCollection(filter);
            this.Add(new FilterCollectionViewModel(filter));
            _filterCollectionNames.Add(filter.CollectionName);
        }

        public void RemoveFilterCollections(IEnumerable<FilterCollectionViewModel> filters)
        {
            foreach (var filter in filters)
            {
                RemoveFilterCollection(filter);
            }
        }

        public void RemoveFilterCollection(FilterCollectionViewModel filter)
        {
            _collection.RemoveFilterCollection(filter.Collection);
            this.Remove(filter);
            _filterCollectionNames.Remove(filter.CollectionName);
        }

        protected void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        public bool ContainsFilterName(string p)
        {
            return (_collection.FirstOrDefault(c => c.Name == p) != null);
        }
    }
}
